//@author A0088498A
package gui;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;

import common.Task;

import memory.History;
import memory.Database;

/**
 * Fake console to allow unit testing to bypass the MainConsole and pass command
 * straight to the Parser and allow output to be written into a separate file <br/>
 * 
 */

public class FakeConsole implements IUserInterface {
	private final String WELCOME_MESSAGE = "Welcome to JimmyMemo!\n";
	private Database _storage;
	private History _history;
	private String _outputFile;
	private BufferedWriter br;

	/**
	 * Constructor
	 * 
	 * @param outputFile
	 *            the file to be written into
	 * @throws IOException
	 *             when the file cannot be opened
	 */
	public FakeConsole(String outputFile) throws IOException {
		_outputFile = outputFile;
		br = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(_outputFile)));
		this.start();
		br.close();
	}

	/**
	 * Print the message with format arguments. <br/>
	 * 
	 * @param msg
	 *            the message to be printed
	 * @param args
	 *            an array of arguments to be formatted into the message
	 */
	public void writeMessage(String msg, String... args) {
		try {
			br = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(_outputFile, true)));

			br.write(String.format(msg, (Object[]) args));
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Write the Tasks information in list format to the screen <br/>
	 * 
	 * @param tasks
	 *            the list of tasks to be formatted
	 */
	public void writeTasks(List<Task> tasks) {
		try {
			br = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(_outputFile, true)));
			int index = 1;
			String tableFormat = "%1$-4s %2$-50s | %3$-50s | %4$-20s | %5$-10s\n";

			String heading = String.format(tableFormat, "", "Task", "Description", "Time", "Status");

			br.write(heading);

			for (Task task : tasks) {
				String name = task.getName();
				String description = task.getDescription();
				if (description.equals("NIL")) {
					description = "";
				}
				String time = task.getDurationString();
				String status = task.getStatus().toString();
				String taskDetail = String.format(tableFormat, index++, name, description, time, status);
				br.write(taskDetail);
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Entry point <br/>
	 * This method should be called after finishing instantiate the console <br/>
	 * 
	 * @throws IOException
	 */
	public void start() throws IOException {
		writeMessage(WELCOME_MESSAGE);
		initialize();
	}

	/**
	 * Initialize other modules: History and Storage <br/>
	 */
	private void initialize() {
		_storage = new Database();
		_history = new History();
	}

	/**
	 * Get the Storage module of this current session
	 * 
	 * @return Storage
	 */
	public Database getStorage() {
		return _storage;
	}

	/**
	 * Get the History module of this current session
	 * 
	 * @return History
	 */
	public History getHistory() {
		return _history;
	}

	/**
	 * "Clear" the console by inserting 50 new lines
	 */
	public void clear() {
		try {
			br = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(_outputFile, true)));
			for (int i = 0; i < 50; i++) {
				br.write("");
			}
			br.close();
		} catch (IOException e) {
			// Exception should be only raise when writer cannot write into
			// files (which should not happen
			e.printStackTrace();
			return;
		}
	}

	/**
	 * Not supported
	 */
	public void writeFreeSlots(List<Task> freeSlots) {
	}

}
